#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

/* seconddrvtest 
  */
#define BIT1 0x02

#define LPC_EC_INDEX_PORT 0x2E
#define LPC_EC_DATA_PORT 0x2F

#define SIO_CONFIG_CTRL       0x02
#define SIO_CONFIG_PORT       0x2E

#define VOID       void
#define UINT8       unsigned char
#define UINT16       unsigned short


#define EC_DEV_IN 1001
#define EC_DEV_OUT 1002

#define EC_DEV_BYTE_IN 1101
#define EC_DEV_BYTE_OUT 1102

typedef struct
{
	int nlen;
	unsigned short int port;
	unsigned char value;

}  __attribute__ ((packed)) typEcDev;

unsigned char dev_inb(int fd, unsigned short int port);
void dev_outb(int fd, unsigned char value, unsigned short int port);

unsigned char dev_inb(int fd, unsigned short int port)
{
	typEcDev ecdev;
	ecdev.port=port;
	if(ioctl(fd,EC_DEV_BYTE_IN,&ecdev)==0)
		return ecdev.value;
	return 0xFF;
}

void dev_outb(int fd, unsigned char value, unsigned short int port)
{
	typEcDev ecdev;
	ecdev.port=port;
	ecdev.value=value;

	ioctl(fd,EC_DEV_BYTE_OUT,&ecdev);
}

static VOID EnterConfigMode (int fd)
{
  UINT8  PnpKey;

  PnpKey = 0x87;
  dev_outb(fd, PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x01;
  dev_outb(fd, PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x55;
  dev_outb(fd, PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x55;
  dev_outb(fd, PnpKey, SIO_CONFIG_PORT);
  
  return;
}

static VOID ExitConfigMode (int fd)
{
  UINT8  RegData = 0x00;

  dev_outb (fd, SIO_CONFIG_CTRL,LPC_EC_INDEX_PORT);
  RegData = dev_inb (fd, LPC_EC_DATA_PORT) | BIT1;
  dev_outb (fd, SIO_CONFIG_CTRL,LPC_EC_INDEX_PORT);  
  dev_outb (fd, RegData,LPC_EC_DATA_PORT);
  
  return;
}

static ssize_t ec_it8733_dev_config(int fd)
{
    int i;
	unsigned char Chipid0,Chipid1 =0;
	UINT16  DataTemp;
  EnterConfigMode(fd);
  EnterConfigMode(fd);
  dev_outb (fd, 0x20,LPC_EC_INDEX_PORT);  
  Chipid0 = dev_inb (fd,LPC_EC_DATA_PORT);
  printf("Chipid0 = %02x \n",Chipid0);

  //ecram_vals[0]=Chipid0;

  dev_outb (fd, 0x21,LPC_EC_INDEX_PORT);
  Chipid1 = dev_inb (fd,LPC_EC_DATA_PORT); 
  printf("Chipid1 = %02x \n",Chipid1);

  dev_outb (fd, 0x22,LPC_EC_INDEX_PORT);

  DataTemp = dev_inb (fd,LPC_EC_DATA_PORT);
  printf("DataTemp = %02x \n",DataTemp);

  return 0;
}

int main(int argc, char **argv)
{
	int fd;
	unsigned char key_vals[256];
	unsigned char ec_line,ec_row,index_num;
	char *endstr;
	int val;
	int i;
	
	fd = open("/dev/ec_it8733", O_RDWR);
	if (fd < 0)
	{
		printf("can't open!\n");
	}

	ec_it8733_dev_config(fd);

	if (argc < 2)
	{
		printf("Parameters error!\n");
		return 0;
	}
	
	if(strcmp(argv[1], "write") == 0)
	{
		if (argc != 4)
		{
			printf("Parameters error!\n");
			return 0;
		}
		else
		{
			val = (strtoul(argv[2],&endstr,16) << 8) | strtoul(argv[3],&endstr,16);
		
			write(fd, &val, 16);
			printf("write addr:0x%x,data:0x%x\n",strtoul(argv[2],&endstr,16),strtoul(argv[3],&endstr,16));
		}
	}
	else if(strcmp(argv[1], "read") == 0)
	{
		memset(key_vals, 0x00, sizeof(key_vals));
		read(fd, key_vals, sizeof(key_vals));
	
		printf("RW 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
		for(ec_line=0;ec_line<16;ec_line++)
		{
			printf("%x0 ",ec_line);
			for(ec_row=0;ec_row<16;ec_row++)
			{
				index_num = ec_line * 16 + ec_row;
				printf("%02x ",key_vals[index_num]);
			}
			printf("\r\n");
		}
	}
	else
	{
		printf("Useless parameters!!!\n");	
	}
#if 1
	char buf[100];
	printf("\n");
	memset(buf,0x00,sizeof(buf));
	ioctl(fd,EC_DEV_IN,&buf) ;
	for(i=0;i<sizeof(buf);i++)
		printf("%02X ",buf[i]);
	printf("\n");

	ioctl(fd,EC_DEV_OUT,&buf) ;

	ioctl(fd,EC_DEV_IN,&buf) ;
	for(i=0;i<sizeof(buf);i++)
		printf("%02X ",buf[i]);
	printf("\n");

	ioctl(fd,EC_DEV_OUT,&buf) ;
	ioctl(fd,EC_DEV_IN,&buf) ;
	for(i=0;i<sizeof(buf);i++)
		printf("%02X ",buf[i]);
	printf("\n");

	ioctl(fd,EC_DEV_OUT,&buf) ;
	ioctl(fd,EC_DEV_IN,&buf) ;
	for(i=0;i<sizeof(buf);i++)
		printf("%02X ",buf[i]);
	printf("\n");
	#endif

	//ioctl(fd,EC_DEV_OUT,&buf) ;
	return 0;
}

